using UnityEditor;
using UnityEngine;

public class ModifyRendererSettings : EditorWindow
{
    private bool isStatic;
    private bool receiveShadows;
    private bool castShadows;
    private bool isGPUInstance;
    private bool isLightmapStatic;
    //public int lodIndex = 2;
    [MenuItem("TA/辅助/修改Renderer状态")]
    public static void ShowWindow()
    {
        GetWindow<ModifyRendererSettings>("Modify Renderer Settings");
    }

    private void OnGUI()
    {
        isStatic = EditorGUILayout.Toggle("是否为 Static 物体", isStatic);
        receiveShadows = EditorGUILayout.Toggle("是否接收阴影", receiveShadows);
        castShadows = EditorGUILayout.Toggle("是否产生阴影", castShadows);
        isGPUInstance = EditorGUILayout.Toggle("是否 GPU Instance", isGPUInstance);
        isLightmapStatic = EditorGUILayout.Toggle("是否 Lightmap Static", isLightmapStatic);
        //lodIndex = EditorGUILayout.IntField("贡献烘培的lod层数", lodIndex);
        if (GUILayout.Button("修改"))
        {
            ModifySelectedObjects();
        }
    }

    private void ModifySelectedObjects()
    {
        GameObject[] selectedObjects = Selection.gameObjects;

        // 第一步：统一修改所有物体的属性
        foreach (GameObject selectedObject in selectedObjects)
        {
            // 修改自身
            ModifyObject(selectedObject);

            // 修改所有子物体
            Transform[] allChildren = selectedObject.GetComponentsInChildren<Transform>();
            foreach (Transform child in allChildren)
            {
                ModifyObject(child.gameObject);
            }
        }

        // 第二步：再次遍历所有物体，处理 LODGroup 相关
        foreach (GameObject selectedObject in selectedObjects)
        {
            HandleLODGroup(selectedObject);

            Transform[] allChildren = selectedObject.GetComponentsInChildren<Transform>();
            foreach (Transform child in allChildren)
            {
                HandleLODGroup(child.gameObject);
            }
        }
    }

    private void ModifyObject(GameObject obj)
    {
        obj.isStatic = isStatic;
        Renderer renderer = obj.GetComponent<Renderer>();
        if (renderer != null)
        {
            renderer.receiveShadows = receiveShadows;
            renderer.shadowCastingMode = castShadows ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off;
            foreach (var mat in renderer.sharedMaterials)
            {
                if (mat != null)
                    mat.enableInstancing = isGPUInstance;
            }
        }
        StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags(obj);
        if (isLightmapStatic)
        {
            flags |= StaticEditorFlags.ContributeGI;
        }
        else
        {
            flags &= ~StaticEditorFlags.ContributeGI;
        }
        GameObjectUtility.SetStaticEditorFlags(obj, flags);
        EditorUtility.SetDirty(obj);
    }

    private void HandleLODGroup(GameObject obj)
    {
        LODGroup lodGroup = obj.GetComponent<LODGroup>();
        if (lodGroup != null)
        {
            var lods = lodGroup.GetLODs();
            int id = lods.Length - 1;
            foreach (Renderer lodRenderer in lods[id].renderers)
            {
                if (lodRenderer is MeshRenderer)
                {
                    MeshFilter mf = lodRenderer.gameObject.GetComponent<MeshFilter>(); ;
                    if (mf && mf.sharedMesh && mf.sharedMesh.triangles.Length < 30)
                        id--;
                }
            }
            id = Mathf.Max(id, 0);
            for (int i = 0; i < lodGroup.lodCount; i++)
            {
                if (i == id)
                    continue;
                foreach (Renderer lodRenderer in lods[i].renderers)
                {
                    if (lodRenderer != null)
                    {
                        // 关闭非第一层的光照贡献
                        StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags(lodRenderer.gameObject);
                        flags &= ~StaticEditorFlags.ContributeGI;
                        GameObjectUtility.SetStaticEditorFlags(lodRenderer.gameObject, flags);
                    }
                }
            }
        }
    }
}